function deepClone (obj, hash = new WeakMap()) {
  // undefind 和null 直接返回
  if (obj == null) return obj
  // 返回一个新的日期对象
  if (obj.constructor === Date) return new Date
  if (obj.constructor === RegExp) return new RegExp
  if (typeof obj !== 'object') return obj

  if (hash.get(obj)) {
    return hash.get(obj)
  }
  let target = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj))
  hash.set(obj, target)
  for (const key in obj) {
    target[key] = deepClone(obj[key], hash)
  }
  return target
}
const map = new Map();
map.set('key', 'value');
map.set('ConardLi', 'code秘密花园');

const set = new Set();
set.add('ConardLi');
set.add('code秘密花园');

const target = {
  field1: 1,
  field2: undefined,
  field3: {
    child: 'child'
  },
  field4: [2, 4, 8],
  empty: null,
  map,
  set,
  bool: new Boolean(true),
  num: new Number(2),
  str: new String(2),
  symbol: Object(Symbol(1)),
  date: new Date(),
  reg: /\d+/,
  error: new Error(),
  func1: () => {
    console.log('code秘密花园');
  },
  func2: function (a, b) {
    return a + b;
  }
};
target.field3.prototype = { ttq: 123 }
target.target = target



let clone = deepClone(target)
// console.log('obj1', target)
console.log('clone', target.field3.prototype)
console.log('clone', clone.field3.prototype)

global.gc()
